Next | Prev | Up | Top | Contents | Index

Including EISA Drivers in the Kernel

This section describes the configuration information needed to add an EISA driver to the kernel.

To add a new kernel-level device driver, you must create your own system file. This file should contain the appropriate directive that tells lboot how to include your driver, and it should specify which memory space will be allocated by your device. The filename must include the .sm suffix and reside in the directory /var/sysgen/system. Because lboot can probe for EISA devices, it can conditionally include an EISA device driver into the kernel.


VECTOR Directive

The system file must have a VECTOR: line in it that causes lboot to check whether a hardware device corresponding to the particular module is connected to the system. If the device is found, and a driver exists, it is included in the kernel.

Synopsis

VECTOR:   bustype=EISA   module=driver_name   [options]
Arguments

bustype

This must be set to "EISA".

module

The drivername declares the name of the object file for the driver and its master.d configuration file, respectively, in the /var/sysgen/boot and /var/sysgen/master.d directories.
The optional fields that can be appended to the VECTOR: directive are:

adapter

The adapter number identifying which EISA bus out of possibly several. Indigo2 systems currently support only a single EISA bus, which is referenced as "adapter=0". You can also use "adapter=*" to reference all possible EISA adapters (as potentially available in future hardware). The default is zero.

ctlr

The device number that differentiates between more than one device of the same type. This number is passed to the driver by the edt structure when multiple devices of the same type are connected. Generally, this number has some correspondence to the minor device number.
A final set of VECTOR: line options probes for and configures address spaces used by the EISA or ISA card. EISA address space is divided into I/O and memory address space.

The VECTOR: line space declarations are a triple of the form:

(space_name, address_offset, size)
Arguments

space_name

Must be either EISAIO or EISAMEM (even for ISA cards).

address_offset and size


Specified in bytes. If the card is an EISA card (as opposed to an ISA card), each card's I/O register space starts at
0x1000 (4K) bytes * slot number
and extends the full 0x1000 (4 KB) to the next slot's space. For ISA cards, the I/O space addresses are not slot dependent, but rather card jumper dependent. They can be in the range starting at byte offset 0x100 (256) and extending up to 0x400 (1024). Similarly, the ISA address space size is card dependent and limited only by the ISA address space size. The EISAMEM space can begin at offset 0xa0000
(640 KB) and extend up to 112 MB.
The VECTOR: fields that use these space declarations are:

iospace1

iospace2

iospace3

These space declarations are defined so that the driver can map to the registers and memory on the card. Typically, iospace1 is used to define the I/O register space to be referenced, and iospace2 and iospace3 are used to gain access to one or two different on-card memory spaces.

exprobe_space

There are two different techniques used to probe for the existence of an EISA or ISA card. For an EISA card, a read is compared to an expected value to determine the existence of a particular EISA card in a slot. Thus, probing for an EISA card is done by specifying a VECTOR: line with an exprobe_space read if the card's unique manufacturer product identifier at each EISA slot's product IS I/O address. The manufacturer's product ID is a 4-bit quantity that is encoded in a format specified by the EISA bus specification.

The general form of exprobe_space allows for a more generalized extensive read/write sequence, which can be used to search for an ISA card at a particular address. The probing is accomplished by writing a value to a register located on the card and then reading it back to verify that a board responds to that location. Do not use a comparison value of 0xff because the bus floats to that value, which would cause the probe command always to believe that it had found a new board.

exprobe_space is specified as a six-tuple consisting of:
(rwseg, bus_space, address, size, value, mask)

rwseg - A sequence of one or more r's or w's indicating a read or write. To test for an EISA card, use a simple r. To test for an ISA card, use wr, which causes the value to be written then reread.

bus_space - Either EISAIO or EISAMEM. The manufacturer ID is located in EISAIO space.

address - The address offset to read. The manufacturer ID is located at 0xzC80, where z is the slot number for EISA cards. ISA cards must specify the address of a register that can be read from and written to.

size - The manufacturer ID is four bytes long, as described below. ISA cards must use the appropriate register width.

value - Compressed 4-byte value to look for (EISA). Non-0xff value for ISA.

mask - A bit mask to specify which bytes of the value to compare against.


EISA Product Identifier (ID)

EISA expansion boards, embedded devices, and system boards have a four-byte product identifier (ID) that can be read from I/O port addresses 0xzC80 through 0xzC83. For example, the slot 1 product ID can be read from I/O port addresses 0x1C80-0x1C83.

The first two bytes (0xzC80 and 0xzC81) contain a compressed representation of the manufacturer code. The manufacturer code is a three-character code (uppercase, ASCII characters in the range of A to Z) chosen by the manufacturer and registered with the firm that distributes the EISA specification.

The manufacturer code "ISA" is used to indicate a generic ISA adapter. The three-character manufacturer code is compressed into three 5-bit values so that it can be incorporated into the two I/O bytes at 0xzC80 and 0xzC81, where z represents the slot number probed.

The compression procedure is:

  1. Find the hexadecimal ASCII value for each letter:

    ASCII for "A"-"Z" : "A" = 0x41, "Z" = 0x5a

  2. Subtract 0x40 from each ASCII value:

    Compressed "A" = 0x41-0x40 = 0x01 = 0000 0001
    Compressed "Z" = 0x5a-0x40 = 0x1A = 0001 1010

  3. Retain five least significant bits for each letter:

    Discard three most significant bits (they are always zero)
    Compressed "A" = 0001. Compressed "Z" = 1010

  4. Compressed code = concatenate "0" and the three 5-bit values:

    "AZA" = 0 00001 11010 00001 (16-bit value)
    0xzC80 = 00000111, 0xzC81h = 01000001

Figure 4-2 shows the format of the product ID (addresses 0xzC80-0xzC83).

Figure 4-2 : Product ID Format The manufacturer ID is located at bytes offset 0xzC80-0xzC83, where z represents the slot number probed. exprobe_space usage when searching for an EISA card is:

exprobe_space = (r, EISAIO, 0xzC80, 4, mfg_id, 0xffffffff)
The first argument (r) specifies that this probe consists of doing a single read. The second argument (EISAIO) declares that the address space is in the EISA register range. 0xzC80 is the offset of the manufacturer's unique ID. The size of this read is four bytes. mfg_id is the compressed 4-byte value that is returned by the particular card being searched for. The last argument is a mask which the mfg_id is ANDed against.

In addition to the system file described above, you must create a master file under /var/sysgen/master.d. (The name of the master file is the same as the name of the object file for the driver, but the master file must not have the ".o" suffix.) The FLAG field of the master file must at least include the character device flag c. (You do not need the s flag for EISA device drivers because lboot can probe for EISA devices.)

A more detailed description of the master file can be found in Chapter 2, "Writing a Device Driver," and in the master(1M) man page.

The following example explores adding an ISA card device driver to the kernel. Assuming that the driver is called isacard.o, the following steps are necessary:

  1. Copy the driver object file isacard.o to /var/sysgen/boot.

  2. Create an isacard.sm system file in /var/sysgen/system.

    The file might contain the following lines:

    VECTOR: bustype=EISA module=isacard ctlr=0 adapter=0
    iospace=(EISAIO,0x300,48) probe_space=(wr,EISAIO,0x300,1, 0x11,0xff)

    VECTOR: bustype=EISA module=isacard ctlr=1 adapter=0
    iospace=(EISAIO,0x330,48) probe_space=(wr,EISAIO,0x330,1,

    0x11,0xff)

    This would allow a kernel to support two of the same ISA cards located at different addresses. A one-byte test for card existence will be made at ISA I/O addresses 0x300 and 0x330. If either card returns the value written at one of those locations, the driver will be included in the kernel. Also a 48-byte ISA register address space will be allocated to the card without a memory address space being allocated in the example above.

  3. Create a master file for the driver in the /var/sysgen/master.d directory. Check /usr/include/sys/major.h for available major device numbers or lboot can assign one. See Chapter 11, "Kernel-level Dynamically Loadable Modules (DLMs)," for more information on loadable drivers and master.d configuration:

    *FlagPrefixSoft#DevDependencies
    cisa60- 

    Note that even though the module name is referred to as isacard, the prefix for each of the driver routines can be independently declared, in this case as simply "isa."


System File Example

To add an EISA driver to the kernel, the system file might look like this:

VECTOR: bustype=EISA module=eisacard ctlr=0 adapter=0
        iospace=(EISAIO,0x1000,0x1000)
        iospace2=(EISAMEM,0xC8000,0x10000)
        exprobe_space=(r,EISAIO,0x1C80,4, 
        0x00008107, 0xffffffff)
VECTOR: bustype=EISA module=eisacard ctlr=1 adapter=0
        iospace=(EISAIO,0x2000,0x1000)
        iospace2=(EISAMEM,0xD8000,0x10000)
        exprobe_space=(r,EISAIO,0x2C80,4, 
        0x00008107, 0xffffffff)
VECTOR: bustype=EISA module=eisacard ctlr=2 adapter=0
        iospace=(EISAIO,0x3000,0x1000)
        iospace2=(EISMEM,0xE8000,0x10000)
        exprobe_space=(r,EISAIO,0x3C80,4,
        0x00008107,0xffffffff)
VECTOR: bustype=EISA module=eisacard ctlr=3 adapter=0
        iospace=(EISAIO,0x3000,0x1000)
        iospace2=(EISMEM,0xF8000,0x10000)
        exprobe_space=(r,EISAIO,0x3C80,4,
        0x00008107,0xffffffff)
This will support up to four cards. In this example, the manufacturer ID is AZA with a product number and revision number of zero. In addition to specifying the I/O register space on a per-slot basis, the VECTOR: lines in the above example also reserve 0x10000 bytes of memory space for each card. Each card placed in the system will be uniquely identified to the system by its ctlr number, which also happens to correspond directly to the slot number (although this is not a requirement).


Next | Prev | Up | Top | Contents | Index